#include<iostream>
#include<unistd.h>
#include<pthread.h>

#define NUM 5

using namespace std;

int cnt=0;
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void* Count(void* args)
{
    pthread_detach(pthread_self());//由于不需要获取线程退出信息，所以直接线程分离，就不用线程等待了。

    uint64_t number=/*static_cast<uint64_t>*/(uint64_t)(args);

    cout<<"pthread:"<<number<<"create successfully"<<endl;

    while(true)
    {
        //为防止多线程并发访问cnt，而造成的数据不一致问题，需要对cnt加锁
        pthread_mutex_lock(&lock);
        pthread_cond_wait(&cond,&lock);//线程在cond环境变量下排队，并释放lock锁

        cout<<"pthread:"<<number<<"      cnt:"<<cnt<<endl;
        cnt++;

        pthread_mutex_unlock(&lock);
        //sleep(3);
    }
}

int main()
{
    //vector<pthread_t> tids;
    for(uint64_t i=0;i<NUM;i++)
    {
        pthread_t tid;
        //细节：i传值，而不是传址，因为传值时，每个线程的i值是独立的，而传址时，i是共享的！
        pthread_create(&tid,nullptr,Count,(void*)i);//由于void* 在64位环境下，其大小是8字节，所以i的类型需要改为uint64_t
        usleep(1000);//防止一下创建多个线程，使多线程同时向屏蔽打印数据，从而导致数据错乱
    }

    cout<<"main begin to ctrl..."<<endl;

    //while(true) sleep(1); //防止新线程还没开始跑，主线程就跑完退出了
    while(true)
    {
        pthread_cond_signal(&cond);//唤醒在cond环境变量的等待队列中排队的一个线程，默认是第一个
        usleep(1000*1000);//每隔一秒唤醒一次
        cout<<"signal one pthread..."<<endl;
    }
    return 0;
}